﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Web;
using System.Net;
using TheLoader.classes;
using System.Threading;
using System.Threading.Tasks;
using TheLoader.Properties;
namespace TheLoader
{
    public partial class Form1 : Form
    {
      
        public string currentUrl = "";
       
        int threadsRunning = 0;
        DateTime dtEnd;
        DateTime dtStart;
        TimeSpan tsCount;
        public int TotalUrls = 0;
        public double TotalSeconds = 0.0d;
        double TotalPages = 0.0;
        TheLoaderResults results;
        TestRun tr = new TestRun();
        #region Properties for Children

        private int _NumberOfUsers = 1;
        private int _NumberOfRuns = 1;
        private int _UserPause = 0;

        public int NumberOfUsers
        {
            get { return _NumberOfUsers; }
            set { _NumberOfUsers = value; }

        }

        public int NumberOfRuns
        {
            get { return _NumberOfRuns; }
            set { _NumberOfRuns = value; }

        }

        public int UserPause
        {
            get { return _UserPause; }
            set { _UserPause = value; }

        }

        #endregion

        public Form1()
        {
            InitializeComponent();
            this.tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;

            this.tabControl1.DrawItem += new DrawItemEventHandler(DisableTab_DrawItem);

            this.tabControl1.Selecting += new TabControlCancelEventHandler(DisableTab_Selecting);

        }

        private void button1_Click(object sender, EventArgs e)
        {
            
            ofd.ShowDialog();
            if (ofd.FileName != null && ofd.FileName != "")
            {
                StreamReader SR;

                SR = File.OpenText(ofd.FileName);

                rtb1.Text = SR.ReadToEnd();

                SR.Close();
            }

        }


        #region Thread Stuff

        private void BuildTestRun()
        {
            tr.TestsCollection.Clear();
            tr.bgbs.Clear();
            tr.bgws.Clear();
            tr.URLs.Clear();
            tr.StatusUpdated += new TestRun.TestRunStatusUpdateHandler(tr_StatusUpdated);
           
            tr.NumberOfUsers = NumberOfUsers;
            tr.NumberOfRuns = NumberOfRuns;
            
                foreach (string s in rtb1.Lines)
                {
                    
                    tr.URLs.Add(s);
                }
          

        }

        private void AddTestsToDataGrid()
        {
            dataGridView1.Rows.Clear();
            foreach (TheLoaderTest test in tr.TestsCollection)
            {
                dataGridView1.Rows.Add(test.TestID, null, null, null);
            }
        }

        private void tr_StatusUpdated(TestRunEventArgs e1, TheLoaderTestEventArgs e)
        {
            threadsLabel.Text = "Threads Running " + tr.threadsRunning;
            if (!e.CurrentTest.IsRunning)
                return;

            try
            {
                foreach (DataGridViewRow dgvr in dataGridView1.Rows)
                {
                    if (dgvr.Cells[0].Value.ToString() == e.ID)
                    {
                        
                        dgvr.Cells[1].Value = e.StartTime;
                        if(e.EndTime.ToString() != "1/1/0001 12:00:00 AM")
                        dgvr.Cells[2].Value = e.EndTime;
                        dgvr.Cells[3].Value = e.CurrentLine;
                        dgvr.Cells[4].Value = e.Duration;
                        dgvr.Cells[5].Value = e.AveragePageTime;
                        dgvr.Cells[6].Value = e.NumberofRuns;
                        dgvr.Cells[7].Value = e.NumberofURLs;

                        Application.DoEvents();

                    }
                }
            }
            catch (Exception ex) {  }
        }

        #endregion

        private void ShowResults()
        {
            tr.results.EndTime = DateTime.Now;
            tr.results.OverallPagesPerSecond = Math.Round(TotalPages / TotalSeconds, 2);
            tr.results.TotalUrlsBrowsed = int.Parse(TotalPages.ToString());
            tr.results.OverallPageLoadAverage = GetTotalPageAverage();

            wb1.Document.Write(tr.results.GetHtml());
            tabControl1.SelectedIndex = 2;
            threadsLabel.Text = "Threads Running " + tr.threadsRunning;
        }

       
        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {

                // Goto a blank HTML page
                wb1.Navigate("about:blank");

                // Wait for the document to load
                while (wb1.Document.Body == null) Application.DoEvents();

                // Now you have full access to the body of a blank HTML page.

                SetButtonCondition();
               

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

       
        protected void UpdateGrid(TheLoaderTestEventArgs e)
        {
            foreach (DataGridViewRow dgvr in dataGridView1.Rows)
            {
                if (dgvr.Cells[0].Value.ToString() == e.ID)
                {
                    dgvr.Cells[1].Value = e.StartTime;
                    
                    Application.DoEvents();
                }
            }
        }

        private double GetTotalPageAverage()
        {
            double Total = 0.0;
            foreach (DataGridViewRow dgvr in dataGridView1.Rows)
            {
                if(dgvr.Cells[5].Value != null)
                 Total += double.Parse(dgvr.Cells[5].Value.ToString());
            }
            Application.DoEvents();
            return Math.Round(Total / dataGridView1.Rows.Count, 2);
           
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (TotalPages == (NumberOfUsers * NumberOfRuns * tr.URLs.Count))
            {
                tr.Stop();
                SetButtonCondition();
                ShowResults();
                
                
            }

            Application.DoEvents();
            double pageAvg = GetTotalPageAverage();
            overallAvgLabel.Text = "Overall Page Load Time: " + pageAvg;
            GetPagesPerSecond();
            pagesPerSecondLabel.Text = TotalPages + " Urls Browsed in " + Math.Round(TotalSeconds, 2) + " Seconds = Pages/Second: " + Math.Round(TotalPages / TotalSeconds, 2);
            threadsLabel.Text = "Threads Running " + tr.threadsRunning;
            Application.DoEvents();

           
           
        }
        
        private void GetPagesPerSecond()
        {
           
                dtEnd = DateTime.Now;
                tsCount = dtEnd.Subtract(dtStart);
           
                double Total = 0.0;
                foreach (DataGridViewRow dgvr in dataGridView1.Rows)
                {
                    if (dgvr.Cells[7].Value != null)
                        Total += int.Parse(dgvr.Cells[7].Value.ToString());
                }
                TotalPages = int.Parse(Total.ToString()); ;
                TotalSeconds = tsCount.TotalSeconds;
               
                
        }
        
        private void timer2_Tick(object sender, EventArgs e)
        {
            double pageAvg = GetTotalPageAverage();
            chart1.Series[0].Points.AddY(pageAvg);
            Application.DoEvents();
        }

        private void rtb1_TextChanged(object sender, EventArgs e)
        {
            totalURLsLabel.Text = "Total URLs: " + rtb1.Lines.Length;
            SetButtonCondition();
        }

        #region Toolbar Collection

        private void tbConfig_Click(object sender, EventArgs e)
        {
            frmConfigure config = new frmConfigure();
            config.myParent = this;
            config.NumberOfRuns = this.NumberOfRuns;
            config.NumberOfUsers = this.NumberOfUsers;
            config.UserPause = this.UserPause;
            config.Show();
            SetButtonCondition();
        }

        private void tbRun_Click(object sender, EventArgs e)
        {
            timer1.Enabled = true;
            timer2.Enabled = true;
            BuildTestRun();

          
            tr.CreateObjects();
            Application.DoEvents();
            AddTestsToDataGrid();
            Application.DoEvents();
            tr.Start();
            Application.DoEvents();
            
            dtStart = DateTime.Now;
            SetButtonCondition();
            Application.DoEvents();
            
        }

        private void tbStop_Click(object sender, EventArgs e)
        {
            //ClearAllThreads();
            tr.Stop();
            SetButtonCondition();
            ShowResults();
            
        }

        private void tbWizard_Click(object sender, EventArgs e)
        {
            TesRecorder t = new TesRecorder();
            t.myParent = this;
            t.Show();
            SetButtonCondition();
        }

        private void tbLoadLinks_Click(object sender, EventArgs e)
        {
            ofd.ShowDialog();
            if (ofd.FileName != null && ofd.FileName != "")
            {
                StreamReader SR;

                SR = File.OpenText(ofd.FileName);

                rtb1.Text = SR.ReadToEnd();

                SR.Close();
            }

            totalURLsLabel.Text = "Total URLs: " + rtb1.Lines.Length;
            SetButtonCondition();
        }

        private void SetButtonCondition()
        {
            bool isRunning = (threadsRunning > 0);

            if (tr.IsRunning)
            {
                tbConfig.Enabled = false;
                tbLoadLinks.Enabled = false;
                tbRun.Enabled = false;
                tbWizard.Enabled = false;
                tbStop.Enabled = true;
                tabControl1.TabPages[0].Enabled = false;
                tabControl1.TabPages[2].Enabled = false;
                tabControl1.TabPages[3].Enabled = false;
                tabControl1.SelectedIndex = 1;
                
            }
            else
            {
                tbConfig.Enabled = true;
                tbLoadLinks.Enabled = true;
                tbRun.Enabled = true;
                tbWizard.Enabled = true;
                tbStop.Enabled = false;

                tabControl1.TabPages[0].Enabled = true;
                tabControl1.TabPages[2].Enabled = true;
                tabControl1.TabPages[3].Enabled = true;

                timer1.Enabled = false;
                timer2.Enabled = false;
                
            }

            if (rtb1.Lines.Length <= 0)
                tbRun.Enabled = false;

            Application.DoEvents();

        }

        #endregion

        #region TabPage Drawing

        //if a tab page is selected, the selecting event will be canceled if it is disabled.

        private void DisableTab_Selecting(object sender, TabControlCancelEventArgs e)
        {

            if (!e.TabPage.Enabled)
            {

                e.Cancel = true;

            }

        }



        //draw a tab page based on whether it is disabled or enabled.

        private void DisableTab_DrawItem(object sender, DrawItemEventArgs e)
        {

            TabControl tabControl = sender as TabControl;

            TabPage page = tabControl.TabPages[e.Index];

            if (!page.Enabled)
            {

                using (SolidBrush brush = new SolidBrush(SystemColors.GrayText))
                {

                    e.Graphics.DrawString(page.Text, page.Font, brush, e.Bounds.X + 3, e.Bounds.Y + 3);

                }

            }

            else
            {

                using (SolidBrush brush = new SolidBrush(page.ForeColor))
                {

                    e.Graphics.DrawString(page.Text, page.Font, brush, e.Bounds.X + 3, e.Bounds.Y + 3);

                }

            }

        }



        //disable a page of a tab control by index

        public void DisableTabPageByIndex(TabControl tabControl, int iPageIndex)
        {

            if (iPageIndex >= tabControl.TabCount || iPageIndex < 0)
            {

                return;

            }



            TabPage tabPage = tabControl.TabPages[iPageIndex];

            tabPage.Enabled = false;

        }



        //enable a tab page by index

        public void EnalbleTabPageByIndex(TabControl tabControl, int iPageIndex)
        {

            if (iPageIndex >= tabControl.TabCount || iPageIndex < 0)
            {

                return;

            }

            TabPage tabPage = tabControl.TabPages[iPageIndex];

            tabPage.Enabled = true;

        }

        #endregion
    }
}
